/*
 * Copyright (c) 2010-2011 Plugger Antonio Begue Ponce. All Rights Reserved.
 *
 * This file is part of Plugger Framework.
 *
 *  Plugger Framework is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License version 3 as published by
 *  the Free Software Foundation.
 *
 *  Plugger Framework is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with Plugger Framework.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.plugger.ui.viewmodel;

import com.jgoodies.binding.PresentationModel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import org.plugger.infrastructure.domainbase.EntityBase;
import org.plugger.infrastructure.repositorybase.IWorkspace;
import org.plugger.ui.base.*;

/**
 * An abstract Editable Controller.
 *
 * @author "Antonio Begue"
 * @version $Revision: 1.0 $
 */
public abstract class EditableViewModel<T extends EntityBase> extends ViewModelBase {
    private IWorkspace ws;
    private ObjectState currentObjectState;
    private T currentEntity;
    private DelegateAction saveAction;
    private PresentationModel<T> presentationModel;

    protected EditableViewModel(IView view) {
        super(view);
        this.currentObjectState = ObjectState.NEW;
        this.currentEntity = null;
        this.saveAction = new DelegateAction("Save", new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                saveCommandHandler(e);
            }
        });
    }

    protected abstract void saveCurrentEntity();
    protected abstract void onCurrentEntitySet(T entity);
    protected abstract void onValidationError();

    protected boolean validateCurrentEntity() {
        if (getCurrentEntity().isValidForPersistence()) {
            return true;
        } else {
            onValidationError();
            return false;
        }
    }

    public void saveCommandHandler(ActionEvent e) {
        getPresentationModel().triggerCommit();
        if (this.validateCurrentEntity()) {
            this.saveCurrentEntity();
            this.setCurrentObjectState(ObjectState.EXISTING);
        }
    }

    /**
     * @return the ws
     */
    public IWorkspace getWs() {
        return ws;
    }

    /**
     * @param ws the ws to set
     */
    public void setWs(IWorkspace ws) {
        this.ws = ws;
    }

    /**
     * @return the currentObjectState
     */
    public ObjectState getCurrentObjectState() {
        return currentObjectState;
    }

    /**
     * @param currentObjectState the currentObjectState to set
     */
    public void setCurrentObjectState(ObjectState currentObjectState) {
        this.currentObjectState = currentObjectState;


        // TODO: if (this._currentObjectState != value) {
        //    this._currentObjectState = value;
        //    this.OnPropertyChanged(EditableViewModel<T>.currentObjectStatePropertyName);
        //}
    }

    /**
     * @return the currentEntity
     */
    public T getCurrentEntity() {
        return currentEntity;
    }

    /**
     * @param currentEntity the currentEntity to set
     */
    public void setCurrentEntity(T currentEntity) {
        // TODO: Verificar if (this._currentEntity != value)
        this.currentEntity = currentEntity;
        this.presentationModel = new PresentationModel<T>(currentEntity);
        this.onCurrentEntitySet(currentEntity);
        // TODO: this._saveCommand.IsEnabled = (this._currentEntity != null);
        // TODO: this.OnPropertyChanged(EditableViewModel<T>.currentEntityPropertyName);
//        Long key = (Long) currentEntity.getKey();
        if (!currentEntity.isNew()) {
            setCurrentObjectState(ObjectState.EXISTING);
        }
    }

    /**
     * @return the saveAction
     */
    public DelegateAction getSaveAction() {
        return saveAction;
    }

    /**
     * @return the presentationModel
     */
    public PresentationModel<T> getPresentationModel() {
        return presentationModel;
    }
}
